using System;
using System.Collections.Generic;
using System.Text;
using agsXMPP;
using agsXMPP.protocol.iq.vcard;
using agsXMPP.protocol.client;
using System.IO;
using agsXMPP.protocol.iq.roster;
using System.Windows.Forms;
using System.Drawing;
using eYap.src.Forms;

namespace eYap.sources.Net
{
    public class FBManager
    {
        MainForm mainForm;
        public MyInfo myInfo;
        string fbServer = "chat.facebook.com";
        public XmppClientConnection xmppClient;

        List<Contact> OnlineContacts;
        ImageList imageList;
        public Dictionary<Jid, String> Roster;
        public delegate void RosterFetchedHandler(List<string> RosterNames);
        public event RosterFetchedHandler OnRosterFetched;

        public delegate void LoginSuccessHandler();
        public delegate void LogoutHandler();
        public delegate void GetMyVCardHandler(IQ iqVcard);
        public delegate void GetRosterItemVCardHandler(IQ iqVcard);

        public event GetMyVCardHandler OnGetMyVCard;
        public event GetRosterItemVCardHandler OnGetRosterItemVCard;
        public event LoginSuccessHandler OnLoginSuccess;
        public event LogoutHandler OnLogout;

        public FBManager(MainForm mainForm)
        {
            this.mainForm = mainForm;
            OnlineContacts = new List<Contact>();
            Roster = new Dictionary<Jid, string>();
            imageList = new ImageList();
            xmppClient = new XmppClientConnection(fbServer, 5222);
            xmppClient.OnLogin += new ObjectHandler(xmppClient_OnLogin);
            xmppClient.OnClose += new ObjectHandler(xmppClient_OnClose);

            xmppClient.OnReadXml += new XmlHandler(xmppClient_OnReadXml);
            xmppClient.OnRosterStart += new ObjectHandler(xmppClient_OnRosterStart);
            xmppClient.OnRosterEnd += new ObjectHandler(xmppClient_OnRosterEnd);
            xmppClient.OnRosterItem += new XmppClientConnection.RosterHandler(xmppClient_OnRosterItem);
            xmppClient.OnPresence += new PresenceHandler(xmppClient_OnPresence);
            xmppClient.OnMessage += new MessageHandler(xmppClient_OnMessage);
        }

        void xmppClient_OnMessage(object sender, agsXMPP.protocol.client.Message msg)
        {
            foreach (Contact contact in OnlineContacts)
            {
                if (contact.jid.ToString() == msg.From.ToString())
                {
                    if (contact.chatControl != null)
                    {
                        if (msg.Chatstate == agsXMPP.protocol.extensions.chatstates.Chatstate.composing)
                        {
                            contact.UpdateContactChatStatus(2);
                            return;
                        }
                        else if (msg.Chatstate == agsXMPP.protocol.extensions.chatstates.Chatstate.active)
                        {
                            if (msg.Body != string.Empty)
                            {
                                contact.UpdateContactChatStatus(1);
                                contact.GetMessage(msg.Body);
                                return;
                            }
                            else
                            {
                                contact.UpdateContactChatStatus(3);
                                return;
                            }

                        }
                    }
                    else
                    {
                        this.mainForm.CreateChatTab(contact.contactListitem);

                        if (msg.Chatstate == agsXMPP.protocol.extensions.chatstates.Chatstate.composing)
                        {
                            contact.UpdateContactChatStatus(2);
                            return;
                        }
                        else if (msg.Chatstate == agsXMPP.protocol.extensions.chatstates.Chatstate.active)
                        {
                            if (msg.Body != string.Empty)
                            {
                                contact.UpdateContactChatStatus(1);
                                contact.GetMessage(msg.Body);
                                return;
                            }
                            else
                            {
                                contact.UpdateContactChatStatus(3);
                                return;
                            }

                        }
                    }
                }
            }
        }

        void xmppClient_OnPresence(object sender, Presence pres)
        {

            if (pres.Type == PresenceType.available && pres.Show == ShowType.NONE)
            {
                foreach (Contact ct in OnlineContacts)
                {
                    if (ct.jid.ToString() == pres.From.ToString())
                    {
                        ct.UpdateContactAvailability(1);
                        return;
                    }
                }

                Contact contact = new Contact(mainForm, pres.From);
                contact.UpdateContactAvailability(1);
                contact.GetVCard(this.xmppClient);
                OnlineContacts.Add(contact);

                return;
            }

            else if (pres.Type == PresenceType.available && pres.Show == ShowType.away)
            {
                Contact contact = new Contact(mainForm, pres.From);
                contact.UpdateContactAvailability(2);
                contact.GetVCard(this.xmppClient);
                OnlineContacts.Add(contact);
                return;
            }

            else if (pres.Type == PresenceType.unavailable)
            {
                foreach (Contact contact in OnlineContacts)
                {
                    if (contact.jid.ToString() == pres.From.ToString())
                    {
                        contact.UpdateContactAvailability(0);
                        contact.RemoveListViewItem();
                        break;
                    }
                }
                return;
            }

            else if (pres.Show == ShowType.away)
            {
                foreach (Contact contact in OnlineContacts)
                {
                    if (contact.jid.ToString() == pres.From.ToString())
                    {
                        contact.UpdateContactAvailability(2);
                        break;
                    }
                }
                return;
            }
        }

        void xmppClient_OnRosterItem(object sender, agsXMPP.protocol.iq.roster.RosterItem item)
        {
        }


        void xmppClient_OnRosterEnd(object sender)
        {
        }

        void xmppClient_OnRosterStart(object sender)
        {
        }

        void xmppClient_OnReadXml(object sender, string xml)
        {
            using (FileStream fs = new FileStream("log.txt", FileMode.Append, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.WriteLine();
                    sw.WriteLine(xml);
                }
            }
        }

        void xmppClient_OnClose(object sender)
        {
            OnLogout();
        }

        void xmppClient_OnLogin(object sender)
        {
            OnLoginSuccess();

            GetMyVCard();
            SendPresence();
            //RequestRoster();
        }

        public void Connect(string username, string password)
        {
            xmppClient.Open(username, password);
        }

        public void RequestRoster()
        {
            xmppClient.RequestRoster();
        }

        public void SendPresence()
        {
            xmppClient.SendMyPresence();
        }

        public void Disconnect()
        {
            xmppClient.Close();
        }

        public void GetRosterItemVCard(Jid jid)
        {
            VcardIq viq = new VcardIq(IqType.get, jid);
            xmppClient.IqGrabber.SendIq(viq, new IqCB(GetRosterItemVCardResult), null);

        }

        private void GetRosterItemVCardResult(object sender, IQ iq, object data)
        {
        }

        public void GetMyVCard()
        {
            VcardIq viq = new VcardIq(IqType.get, xmppClient.MyJID);
            xmppClient.IqGrabber.SendIq(viq, new IqCB(MyVcardGetResult), null);
        }

        private void MyVcardGetResult(object sender, IQ iq, object data)
        {
            OnGetMyVCard(iq);
        }

    }

    public struct MyInfo
    {
        public string Name;
        public Image photo;

        public MyInfo(string name, Image pic)
        {
            Name = name;
            photo = pic;
        }
    }
}
